package utils;

import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class XMLHelper
{
	
	
	
	final static String SolverNodeName="solver";
	final static String SolverName = "name";
	final static String SolverPath = "path";
	final static String SolverReqParam = "reqParam";
	final static String SolverParamTypes = "paramTypes";
	final static String SolverType = "type";

	ArrayList<String> services;
	ArrayList<SolverInfo> solvers;

	DocumentBuilderFactory dbf;
	DocumentBuilder db;
	Document doc;

	public ArrayList<String> getServices()
	{
		return services;
	}

	public void setServices(ArrayList<String> services)
	{
		this.services = services;
	}

	public XMLHelper()
	{
		services = new ArrayList<String>();
		solvers = new ArrayList<SolverInfo>();
		dbf = DocumentBuilderFactory.newInstance();
		dbf.setNamespaceAware(true);
		try
		{
			db = dbf.newDocumentBuilder();
		}
		catch (Exception exc)
		{
			exc.printStackTrace();
		}
		String globusLocation = System.getenv("GLOBUS_LOCATION");

		globusLocation += "\\";

		//GetFilesForServices(globusLocation);
		GetFilesForServices("C:\\ws-core-4.0.5\\etc\\org_globus_examples_services_core_rp");

		String curDir = System.getProperty("user.dir");
		File file = new File(curDir + "\\solvers.xml");
		try
		{
			doc = db.parse(file);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

		ParseNodesForSolvers(doc.getChildNodes());

		System.out.println("Nr of services found:" + services.size());
	}

	void GetFilesForServices(String path)
	{
		File globusRoot = new File(path);
		FilenameFilter filter = new FilenameFilter()
		{
			@Override
			public boolean accept(File arg0, String arg1)
			{

				File directory = new File(arg0.getAbsolutePath() + "\\" + arg1);
				if (directory.isDirectory())
				{
					return true;
				}
				if (arg1.contains(".xml"))
				{
					return true;
				}
				return false;
			}
		};
		File[] files = globusRoot.listFiles(filter);

		for (int i = 0; i < files.length; i++)
		{
			try
			{
				if (files[i].isDirectory())
				{
					GetFilesForServices(files[i].getAbsolutePath());
				}
				else

				{
					doc = db.parse(new File(files[i].getAbsolutePath()));
					ParseNodesForServices(doc.getChildNodes());
				}
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
	}

	void ParseNodesForSolvers(NodeList nodeList)
	{

		try
		{

			if (nodeList.getLength() > 0)
			{
				for (int i = 0; i < nodeList.getLength(); i++)
				{
					Node node = (Node) nodeList.item(i);
					if (node.getNodeName() == XMLHelper.SolverNodeName)
					{
						SolverInfo info = new SolverInfo();
						info
								.setName(node.getAttributes().getNamedItem(
										XMLHelper.SolverName).getNodeValue()
										.toString());
						info
								.setPath(node.getAttributes().getNamedItem(
										XMLHelper.SolverPath).getNodeValue()
										.toString());

						String filenamesString = node.getAttributes()
								.getNamedItem(XMLHelper.SolverReqParam)
								.getNodeValue().toString();
						if(filenamesString.length()>0)
						{
						String[] filenames = filenamesString
								.split(ReflectionHelper.SEPARATOR);
						String parameters = "";
						for (int j = 0; j < filenames.length; j++)
						{
							Object obj = SerializeHelper
									.GetObjectFromFile(filenames[j]);
							parameters = parameters
									+ SerializeHelper.GetStringFromObject(obj)
									+ ReflectionHelper.SEPARATOR;
						}
						
						info.setReqParam(parameters.substring(0, parameters
								.length()
								- ReflectionHelper.SEPARATOR.length()));
						}
						else
						{
							info.setReqParam("");
						}
						info.setParamTypes(node.getAttributes().getNamedItem(
								XMLHelper.SolverParamTypes).getNodeValue()
								.toString());

						info.setServiceType(ServiceType.valueOf(node
								.getAttributes().getNamedItem(
										XMLHelper.SolverType).getNodeValue()));
						solvers.add(info);
					}
					NodeList currentNodeList = node.getChildNodes();
					ParseNodesForSolvers(currentNodeList);
				}
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

	}

	void ParseNodesForServices(NodeList nodeList)
	{
		if (nodeList.getLength() > 0)
		{
			for (int i = 0; i < nodeList.getLength(); i++)
			{
				Node node = (Node) nodeList.item(i);
				if (node.getNodeName() == "service")
				{
					services.add(node.getAttributes().getNamedItem("name")
							.getNodeValue().toString());
				}
				NodeList currentNodeList = node.getChildNodes();
				ParseNodesForServices(currentNodeList);
			}
		}
	}

	public ArrayList<SolverInfo> getSolvers()
	{
		return solvers;
	}

	public void setSolvers(ArrayList<SolverInfo> solvers)
	{
		this.solvers = solvers;
	}

}
